package com.jwsoft.manager.core.util;

import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jwsoft.manager.common.vo.eduSchool.EduSchoolVO;
import com.jwsoft.manager.core.dao.model.EduClass;
import com.jwsoft.manager.core.dao.model.EduClassSetting;
import com.jwsoft.manager.core.dao.model.EduClassStudent;
import com.jwsoft.manager.core.dao.service.EduClassService;
import com.jwsoft.manager.core.dao.service.EduClassStudentService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 分班工具类
 */
@Component
public class BandingStudentHelper {
    @Autowired
    EduClassService eduClassService;
    @Autowired
    EduClassStudentService eduClassStudentService;

    public void banding(EduClassSetting setting, List<EduClass> classList, EduSchoolVO eduSchoolVO) {

        //获取学生信息
        QueryWrapper<EduClassStudent> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(EduClassStudent::getSchoolId, setting.getSchoolId())
                .eq(StringUtils.isNotBlank(setting.getConfigTypeName()), EduClassStudent::getConfigTypeName, setting.getConfigTypeName())
                .eq(EduClassStudent::getYear, setting.getYear());
        Boolean sexFlag = false;
        if (StringUtils.isNotBlank(setting.getClassParams())) {
            List<String> codeList = Arrays.stream(setting.getClassParams().split(",")).map(s -> s).collect(Collectors.toList());
            for (String code : codeList) {
                if ("class0001".equalsIgnoreCase(code)) {
                    //性别
                    sexFlag = true;
                    queryWrapper.lambda().orderByAsc(EduClassStudent::getSex);
                }
                if ("class0002".equalsIgnoreCase(code)) {
                    //年龄
                    queryWrapper.lambda().orderByAsc(EduClassStudent::getAge);
                }
                if ("class0003".equalsIgnoreCase(code)) {
                    //居住地
                    queryWrapper.lambda().orderByAsc(EduClassStudent::getAddress);
                }
                if ("class0004".equalsIgnoreCase(code)) {
                    //总成绩
                    queryWrapper.lambda().orderByDesc(EduClassStudent::getScore);
                }
                if ("class0005".equalsIgnoreCase(code)) {
                    //语文成绩
                    queryWrapper.lambda().orderByDesc(EduClassStudent::getScoreChinese);
                }
                if ("class0006".equalsIgnoreCase(code)) {
                    //数学成绩
                    queryWrapper.lambda().orderByDesc(EduClassStudent::getScoreMathematics);
                }
                if ("class0007".equalsIgnoreCase(code)) {
                    //英语成绩
                    queryWrapper.lambda().orderByDesc(EduClassStudent::getScoreEnglish);
                }
                if ("class0008".equalsIgnoreCase(code)) {
                    //姓名
                    queryWrapper.lambda().orderByAsc(EduClassStudent::getFullName);
                }
                if ("class0009".equalsIgnoreCase(code)) {
                    //特长生均衡
                    queryWrapper.lambda().orderByAsc(EduClassStudent::getSpecialityFlag);
                }
                if ("class0010".equalsIgnoreCase(code)) {
                    //本地/外地户籍均衡
                    queryWrapper.lambda().orderByDesc(EduClassStudent::getFollowingFlag);
                }
            }
        }
        List<EduClassStudent> studentList = eduClassStudentService.list(queryWrapper);
        if (CollectionUtils.isEmpty(studentList)) {
            return;
        }
        Integer classNum = setting.getClassNum();
        List<Integer> xhList = classList.stream().map(EduClass::getOrderNumber).collect(Collectors.toList());
        Map<Integer, EduClass> classMap = classList.stream().collect(Collectors.toMap(EduClass::getOrderNumber, a -> a, (k1, k2) -> k1));
        List<EduClassStudent> allList = new ArrayList<>();//所有学生
        List<EduClassStudent> syList = new ArrayList<>();//剩余的学生
        if (sexFlag) {
            //男女比例
            Map<String, List<EduClassStudent>> groupBy = studentList.stream().collect(Collectors.groupingBy(EduClassStudent::getSex));
            List<EduClassStudent> bodyList = groupBy.get("1");//男
            List<EduClassStudent> gridList = groupBy.get("2");//女
            Integer body = 0;
            if (!CollectionUtils.isEmpty(bodyList)) {
                body = bodyList.size() / classNum;
            }
            Integer grid = 0;
            if (!CollectionUtils.isEmpty(gridList)) {
                grid = gridList.size() / classNum;
            }
            if (body <= 0) {
                for (int i = 0; i < bodyList.size(); i++) {
                    EduClassStudent student = bodyList.get(i);
                    student.setSerialNumber(1);
                    syList.add(student);

                }
            } else {
                for (int i = 1; i <= body; i++) {
                    Set<Integer> sj = RandomUtil.randomEleSet(xhList, classNum);
                    int f = (i - 1) * classNum - 1;
                    int g = 0;
                    for (int j : sj) {
                        int k = f + j;
                        g = g + 1;
                        EduClassStudent student = bodyList.get(k);
                        EduClass eduClass = classMap.get(g);
                        if (eduClass != null) {
                            student.setClassId(eduClass.getClassId());
                        } else {
                            student.setClassId(0L);
                        }
                        student.setSerialNumber(i);
                        allList.add(student);
                    }
                }
                if (bodyList.size() > body * classNum) {
                    int k = body * classNum;
                    for (int i = k; i < bodyList.size(); i++) {
                        EduClassStudent student = bodyList.get(i);
                        student.setSerialNumber(body + 1);
                        syList.add(student);

                    }
                }
            }
            //女生
            if (grid <= 0) {
                for (int i = 0; i < gridList.size(); i++) {
                    EduClassStudent student = gridList.get(i);
                    student.setSerialNumber(1);
                    syList.add(student);

                }
            } else {
                for (int i = 1; i <= grid; i++) {
                    Set<Integer> sj = RandomUtil.randomEleSet(xhList, classNum);
                    int f = (i - 1) * classNum - 1;
                    int g = 0;
                    for (int j : sj) {
                        int k = f + j;
                        g = g + 1;
                        EduClassStudent student = gridList.get(k);
                        EduClass eduClass = classMap.get(g);
                        if (eduClass != null) {
                            student.setClassId(eduClass.getClassId());
                        } else {
                            student.setClassId(0L);
                        }
                        student.setSerialNumber(i);
                        allList.add(student);
                    }
                }
                if (gridList.size() > grid * classNum) {
                    int k = grid * classNum;
                    for (int i = k; i < gridList.size(); i++) {
                        EduClassStudent student = gridList.get(i);
                        student.setSerialNumber(grid + 1);
                        syList.add(student);
                    }
                }
            }

        } else {
            Integer body = 0;
            if (!CollectionUtils.isEmpty(studentList)) {
                body = studentList.size() / classNum;
            }
            if (body <= 0) {
                for (int i = 0; i < studentList.size(); i++) {
                    EduClassStudent student = studentList.get(i);
                    student.setSerialNumber(1);
                    syList.add(student);

                }
            } else {
                for (int i = 1; i <= body; i++) {
                    Set<Integer> sj = RandomUtil.randomEleSet(xhList, classNum);
                    int f = (i - 1) * classNum - 1;
                    int g = 0;
                    for (int j : sj) {
                        int k = f + j;
                        g = g + 1;
                        EduClassStudent student = studentList.get(k);
                        EduClass eduClass = classMap.get(g);
                        if (eduClass != null) {
                            student.setClassId(eduClass.getClassId());
                        } else {
                            student.setClassId(0L);
                        }
                        student.setSerialNumber(i);
                        allList.add(student);
                    }
                }
                if (studentList.size() > body * classNum) {
                    int k = body * classNum;
                    for (int i = k; i < studentList.size(); i++) {
                        EduClassStudent student = studentList.get(i);
                        student.setSerialNumber(body + 1);
                        syList.add(student);

                    }
                }
            }
        }
        if (!CollectionUtils.isEmpty(syList)) {
            Set<Integer> sj = RandomUtil.randomEleSet(xhList, classNum);
            List<Integer> sjList = new ArrayList(sj);
            int i = 0;
            for (EduClassStudent student : syList) {
                if (i >= classNum) {
                    i = 0;
                }
                Integer j = sjList.get(i);
                EduClass eduClass = classMap.get(j);
                if (eduClass != null) {
                    student.setClassId(eduClass.getClassId());
                } else {
                    student.setClassId(0L);
                }
                allList.add(student);
                i = i + 1;
            }

        }
        Map<Long, List<EduClassStudent>> studentGroup = allList.stream().collect(Collectors.groupingBy(EduClassStudent::getClassId));
        for (EduClass eduClass : classList) {
            List<EduClassStudent> students = studentGroup.get(eduClass.getClassId());
            if (!CollectionUtils.isEmpty(students)) {
                int total = 0;
                int body = 0;
                int grid = 0;
                for (EduClassStudent student : students) {
                    if ("1".equalsIgnoreCase(student.getSex())) {
                        body = body + 1;
                    } else {
                        grid = grid + 1;
                    }
                    total = total + 1;
                    student.setAdviserId(null);
                }
                eduClass.setTotal(total);
                eduClass.setSchoolboy(body);
                eduClass.setSchoolgirl(grid);
            }
            eduClassStudentService.updateBatchById(students);
        }
        eduClassService.updateBatchById(classList);
    }
}
